package line;
import java.awt.Color;
import java.awt.Graphics2D;
import point.ObjectPoint;
import environment.Simulation;
import force.ForceVector;

/**
 * 
 * @author Mechael Deng(mjd24), Xi Du(xd14)
 *
 */
public abstract class Line {
   
    /**
     * no magic number.
     */
    private static final double WHITE = 0.001;

    /**
     * @param myStart
     */
    private  ObjectPoint myStart;
    /**
     * @param myEnd
     */
    private  ObjectPoint myEnd;
    /**
     * @param myLength
     */
    private double myLength;
    /**
     * @param myK
     */
    private  double myK;

 /**
  * The constructor of Line class.
  * @param start start point
  * @param end end point
  * @param length the rest length
  * @param kVal k factor
  */
    public Line(final ObjectPoint start, final ObjectPoint end,
            final double length, final double kVal) {
        myStart = start;
        myEnd = end;
        myLength = length;
        myK = kVal;
    }

    /**
     * 
     * @param pen Graphics
     */
    public final void paint(final Graphics2D pen) {
        int xStart = (int) myStart.getCenter().getX();
        int yStart = (int) myStart.getCenter().getY();
        int xEnd = (int) myEnd.getCenter().getX();
        int yEnd = (int) myEnd.getCenter().getY();
        double dx = xStart - xEnd;
        double dy = yStart - yEnd;
        double len = Math.sqrt(dx * dx + dy * dy) - myLength;

        if (Math.abs(len) < WHITE) {
            pen.setColor(Color.WHITE);
        }
        else if (len < 0.0) {
            pen.setColor(Color.BLUE);
        }
        else {
            pen.setColor(Color.RED);
        }
        pen.drawLine(xStart, yStart, xEnd, yEnd);
    }

    public final double getdx(){
        return getmyStart().getCenter().getX()-getmyEnd().getCenter().getX();
    }
    public final double getdy(){
        return getmyStart().getCenter().getY()-getmyEnd().getCenter().getY();
    }
    public final double getDistance(){
        double originalLength = ForceVector.distanceBetween(getdx(), getdy());
        return originalLength;
    }
    public final double getAngle(){
        double angle = ForceVector.angleBetween(getdx(), getdy());
        return angle;
    }
    public final void applyHookesForce(double myK, double distance){
        ForceVector f = new ForceVector(getAngle(), myK * (getmyLength() - distance));
        getmyStart().applyForce(f);
        f.negate();
        getmyEnd().applyForce(f);
        
    }
    
    
/**
 * 
 * @param canvas container
 * @param dt time
 */
    public abstract void update(final Simulation canvas, final double dt);
    /**
     *
     * @return start point
     */
    public final  ObjectPoint getmyStart() {
        return myStart;
    }
    /**
     *
     * @return end point
     */
    public final ObjectPoint getmyEnd() {
        return myEnd;
    }
    /**
     * 
     * @return k factor
     */
    public final double getmyK() {
        return myK;
    }
    /**
     * 
     * @return rest length
     */
    public final double getmyLength() {
        return myLength;
    }
}
